本文参考 Beautiful Soup官方文档 ,做学习记录用
一、初始化
导入 BeautifulSoup4 包:
|
|
在构造 BeautifulSoup 对象时, BeautifulSoup 首先文档被转换成Unicode,并且HTML的实例都被转换成Unicode编码, 然后BeautifulSoup 使用指定的网页解析器来解析这段文档
关于解析器的描述参考官方文档, BeautifulSoup 根据当前系统安装的库自动选择解析器,解析器的优先数序: lxml, html5lib, html.paser, 推荐用 lxml 这个速度更快的解析器
构造 BeautifulSoup 对象:
|
|
当使用 lxml 解析器时,Beautiful Soup 将复杂HTML文档转换成一个复杂的DOM树结构进行解析:
每个节点都是Python对象,所有对象可以归纳为4种: Tag, NavigableString, BeautifulSoup, Comment
这里只介绍简单的 tag 对象的方法, 其他对象参考官方文档
二、find_all 方法
find_all() 几乎是 Beautiful Soup 中最常用的搜索方法; find_all 可以通过 tag 的名字或者属性等进行搜索,也可以将这个搜索策略结合起来搜索, find_all 根据你输入的策略找到所有符合要求的 tag,以 list 的方式返回。
|
|
2.1 搜索标签名字(name):
|
|
2.2 搜索属性(attrs):
|
|
2.3 搜索文字(text):
注意,文字的搜索会导致其他搜索给的值如:tag, attrs都失效。
方法与搜索便签名字一样
2.4 recursive, limit:
recursive=False表示只搜索直接儿子,否则搜索整个子树,默认为True。
当使用findAll或者类似返回list的方法时,limit属性用于限制返回的数量,如findAll(‘p’, limit=2): 返回首先找到的两个tag
2.5 像调用 find_all() 一样调用tag:
由于find_all() 几乎是Beautiful Soup中最常用的搜索方法,所以我们定义了它的简写方法. BeautifulSoup 对象和 tag 对象可以被当作一个方法来使用,这个方法的执行结果与调用这个对象的 find_all() 方法相同;
下面两行代码是等价的:
|
|
这两行代码也是等价的:
|
|
三、find 方法
find_all() 方法将返回文档中符合条件的所有tag,尽管有时候我们只想得到一个结果.比如文档中只有一个
标签,那么使用 find_all() 方法来查找标签就不太合适, 使用 find_all 方法并设置 limit=1 参数不如直接使用 find() 方法.下面两行代码是等价的:
|
|
唯一的区别是 find_all() 方法的返回结果是值包含一个元素的列表,而 find() 方法直接返回第一个符合条件的tag
find_all() 方法没有找到目标是返回空列表, find() 方法找不到目标时,返回 None .
|
|
可以使用 soup.head.title 这种方式直接得到子节点,其中 head 和 title 是 tag的名字;
这个简写的原理就是调用当前 tag 的 find() 方法:
|
|
四、tag结点之间的关系
4.1 子节点:
tag的 .contents
属性可以将tag的子节点以列表的方式输出:
|
|
4.2 父节点:
通过 .parent
属性来获取某个元素的父节点:
|
|
4.3 兄弟结点:
在文档树中,使用 .next_sibling
和 .previous_sibling
属性来查询兄弟节点:
|
|
实际文档中的tag的 .next_sibling
和 .previous_sibling
属性通常是字符串或空白,因为空白或者换行也可以被视作一个节点,所以得到的结果可能是空白或者换行,所以在使用兄弟节点时需要注意这个坑!
五、输出
通过上述的方法找到了便签之后,需要将标签中相应的信息进行输出
5.1 格式化输出:
prettify() 方法将Beautiful Soup的文档树格式化后以Unicode编码输出,每个XML/HTML标签都独占一行
|
|
BeautifulSoup 对象和它的tag节点都可以调用 prettify() 方法:
|
|
5.2 get_text():
如果只想得到tag中包含的文本内容,那么可以调用 get_text() 方法,这个方法获取到tag中包含的所有文本内容包括子孙tag中的内容,并将结果作为Unicode字符串返回:
|
|
5.3 得到便签的属性:
一个tag可能有很多个属性. tag 有一个 “class” 的属性,值为 “boldest” ;
tag的属性的操作方法与字典相同:
|
|